/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.netbeans.shapesimple;


import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import javax.swing.JComponent;
import org.netbeans.api.visual.action.AcceptProvider;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.ConnectorState;
import org.netbeans.api.visual.action.TextFieldInplaceEditor;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.border.Border;
import org.netbeans.api.visual.border.BorderFactory;
import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.model.ObjectState;
import org.netbeans.api.visual.widget.LabelWidget;
import org.netbeans.api.visual.widget.LayerWidget;
import org.netbeans.api.visual.widget.Scene;
import org.netbeans.api.visual.widget.Widget;
import org.netbeans.api.visual.widget.general.IconNodeWidget;
import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;


/**
 *
 * @author rejun001
 */
public class GraphSceneImpl extends GraphScene<MyNode, String>
{

    private LayerWidget mainLayer;
    private LayerWidget connectionLayer;
    private LayerWidget interactionLayer;
    
    private static final Border RESIZE_BORDER = 
            BorderFactory.createResizeBorder( 8, Color.BLACK, true);
    private static final Border DEFAULT_BORDER = 
            BorderFactory.createEmptyBorder( 8 );
    
    
    private WidgetAction editorAction = ActionFactory.createInplaceEditorAction( new LabelTextFieldEditor() );


    public GraphSceneImpl()
    {
        mainLayer = new LayerWidget( this );
        addChild( mainLayer );

        getActions().addAction( ActionFactory.createAcceptAction( new AcceptProvider()
        {
            @Override
            public ConnectorState isAcceptable( Widget widget , Point point , Transferable t )
            {
                Image dragImage = getImageFromTransferable( t );
                JComponent view = getView();
                Graphics2D g2 = (Graphics2D) view.getGraphics();
                Rectangle visRect = view.getVisibleRect();
                view.paintImmediately( visRect.x , visRect.y , visRect.width , visRect.height );
                g2.drawImage( dragImage ,
                        AffineTransform.getTranslateInstance( point.getLocation().getX() ,
                        point.getLocation().getY() ) ,
                        null );
                return ConnectorState.ACCEPT;
            }


            @Override
            public void accept( Widget widget , Point point , Transferable t )
            {
                Image image = getImageFromTransferable(t);
                Widget w = GraphSceneImpl.this.addNode( new MyNode(image));
                w.setPreferredLocation( widget.convertLocalToScene( point));
            }

        } ) );
        
        getActions().addAction(ActionFactory.createZoomAction());
    }


//    @Override
//    protected Widget attachNodeWidget( Object n )
//    {
//        return null;
//    }
//
//
//    @Override
//    protected Widget attachEdgeWidget( Object e )
//    {
//        return null;
//    }
//
//
//    @Override
//    protected void attachEdgeSourceAnchor( Object e , Object n , Object n1 )
//    {
//    }
//
//
//    @Override
//    protected void attachEdgeTargetAnchor( Object e , Object n , Object n1 )
//    {
//    }
    
    private Image getImageFromTransferable(Transferable t)
    {
        Object o = null;
        try
        {
            o = t.getTransferData( DataFlavor.imageFlavor );
        }
        catch ( IOException e )
        {
            Exceptions.printStackTrace( e );
        }
        catch (UnsupportedFlavorException e)
        {
            Exceptions.printStackTrace( e );
        }
        return o instanceof Image ? (Image) o : ImageUtilities.loadImage( "org/netbeans/shapesimple/palette/image1.png");
    }


    @Override
    protected Widget attachNodeWidget( MyNode n )
    {
        //TriangleWidget widget = new TriangleWidget( this , n, "blah");
        IconNodeWidget widget = new IconNodeWidget( this );
        widget.setImage( n.getImage());
        widget.setLabel( Long.toString( n.hashCode()));
        
        // double-click
        widget.getLabelWidget().getActions().addAction( editorAction);
        
        // single-click
        widget.getActions().addAction( createSelectAction());
        
        // mouse dragged
        widget.getActions().addAction(ActionFactory.createMoveAction());
//        widget.getActions().addAction( ActionFactory.createAlignWithMoveAction(
//                mainLayer, interactionLayer, 
//                ActionFactory.createDefaultAlignWithMoveDecorator()) );
        
        // mouse-over
        widget.getActions().addAction( createObjectHoverAction());
 
        mainLayer.addChild( widget );
        return widget;
    }


    @Override
    protected Widget attachEdgeWidget( String e )
    {
        return null;
    }


    @Override
    protected void attachEdgeSourceAnchor( String e , MyNode n , MyNode n1 )
    {
    }


    @Override
    protected void attachEdgeTargetAnchor( String e , MyNode n , MyNode n1 )
    {
    }
    
    private class LabelTextFieldEditor implements TextFieldInplaceEditor
    {


        @Override
        public boolean isEnabled( Widget widget )
        {
            return true;
        }


        @Override
        public String getText( Widget widget )
        {
            return ((LabelWidget) widget).getLabel();
        }


        @Override
        public void setText( Widget widget , String text )
        {
            ((LabelWidget) widget).setLabel( text);
        }
        
    }
    
    private static final class TriangleWidget extends IconNodeWidget
    {


        public TriangleWidget( Scene scene, Image shape, String name )
        {
            super( scene );
            setLabel(name);
            setImage(shape);
            setPreferredLocation( new Point(10,20));
            getActions().addAction(ActionFactory.createMoveAction());
            getActions().addAction( scene.createWidgetHoverAction());
        }


        @Override
        public void notifyStateChanged( ObjectState previousState , ObjectState state )
        {
            super.notifyStateChanged( previousState , state ); 
            getImageWidget().setBorder(
                    state.isSelected() ? (
                    state.isHovered() ? RESIZE_BORDER : DEFAULT_BORDER) : (
                    state.isHovered() ? RESIZE_BORDER : DEFAULT_BORDER));
        }
        
        
        
    }

}
